package com.micro.business.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * <P>日期类工具</P>
 *
 * @author 高仕立
 * @date 2018/8/31 下午2:09
 * @since
 */
public class DateUtil {

    /**
     * 日期格式e.g. 08:00
     */
    public static final String FORMAT_H_M = "HH:mm";

    /**
     * 日期格式e.g. 1991-01-01
     */
    public static final String FORMAT_Y_M_D = "yyyy-MM-dd";

    /**
     * 日期格式e.g. 1991-01-01 09:00
     */
    public static final String FORMAT_Y_M_D_H_M = "yyyy-MM-dd HH:mm";

    /**
     * 日期格式e.g. 1991-01-01 09:00:00
     */
    public static final String FORMAT_Y_M_D_H_M_S = "yyyy-MM-dd HH:mm:ss";

    /**
     * 日期格式
     */
    public static final String FORMAT_Y_M_D_H_M1 = "yyyy/MM/dd HH:mm";

    /**
     * 日期格式e.g. 01-01 09:00
     */
    public static final String FORMAT_M_D_H_M = "MM月dd日 HH:mm";

    /**
     * 日期格式e.g. 01-01
     */
    public static final String FORMAT_M_D_2 = "MM月dd日";

    /**
     * 日期格式 e.g. 07/02 08:00
     */
    public static final String FORMAT_M_D_H_M_1 = "MM/dd HH:mm";

    /**
     * 日期格式 e.g. 07/02
     */
    public static final String FORMAT_M_D = "MM/dd";
    
    public static final int H_M = 0;
    
    public static final int H_M_S = 1;
    
    public static final int Y_H_M = 2;
    
    public static final int Y_H_M_H_M = 3;
    
    public static final int Y_H_M_H_M_S = 4;
    
    public static final int Y = 5;
    
    public static final int Y_H = 6;
    
    public static final int Y_H_M_H_M_S_2 = 7;
    
    public static final int YMD_HM = 8;
    
    public static final int MD = 9;
    
    public static final int YMD = 10;
    
    public static final int YMD_2 = 11;
    
    public static final int MD_CN = 12;


    /**
     * 日期操作增加类型：天
     */
    private static final int ADD_TYPE_DATE = 1;

    /**
     * 日期操作增加类型：时
     */
    private static final int ADD_TYPE_HOUR = 2;

    /**
     * 日期操作增加类型：分
     */
    private static final int ADD_TYPE_MINUTE = 3;

    /**
     * 日期操作增加类型：秒
     */
    private static final int ADD_TYPE_SECOND = 4;

    /**
     * 日期操作增加类型：月
     */
    private static final int ADD_TYPE_MONTH = 5;

    /**
     * 日期操作增加类型：年
     */
    private static final int ADD_TYPE_YEAR = 6;
    
    /**
     * 日期格式化：yyyy-MM-dd HH:mm:ss
     */
    public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
    /**
     * 日期格式化：yyyy-MM-dd
     */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    /**
     * 日期格式化：yyyy-MM-dd
     */
    public static final String LIST_DATE_FORMAT = "yyyy.MM.dd";
    
    /**
     * 日期格式化：HH:mm:ss
     */
    private static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";


    /**
     * 24小时时间格式
     */
    public static final String DEFAULT_DATETIME_FORMAT2 = "yyyy-MM-dd";

    /**
     * 24小时时间格式
     */
    public static final String DEFAULT_DATETIME_FORMAT1 = "yyyy-MM-dd HH:mm";

    public static final String DEFAULT_DATETIME_FORMAT3 = "yyyy.MM.dd HH:mm";

    /**
     * 24小时时间格式,包含毫秒
     */
    public static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";

    public static final String DEFAULT_MONTHDAY_FORMAT = "MM月dd日";

    public static final String DEFAULT_MDHM_FORMAT = "MM月dd日 HH:mm";

    public static final String DEFAULT_OFFLINE_MSG_FORMAT = "MM月dd日 HH:mm:ss";

    public static final String DEFAULT_HM_FORMAT = "HH:mm";

    /**
     * 格式：2016/12/20、 24小时时间格式
     */
    public static final String DEFAULT_TIME_FORMAT1 = "yyyy/MM/dd";

    public static final String DEFAULT_DATE_FORMAT1 = "yyyy.MM.dd";

    public static final String DEFAULT_TIME_FORMAT2 = "MM/dd HH:mm";


    /**
     * 英文简写（默认）如：2010-12-01
     */
    public static final String FORMAT_SHORT = "yyyy/MM/dd";

    /**
     * 英文全称 如：2010-12-01 23:15:06
     */
    public static final String FORMAT_LONG = "yyyy-MM-dd HH:mm:ss";

    /**
     * 精确到毫秒的完整时间 如：yyyy-MM-dd HH:mm:ss.S
     */
    public static final String FORMAT_FULL = "yyyy-MM-dd HH:mm:ss.S";

    /**
     * 中文简写 如：2010年12月01日
     */
    public static final String FORMAT_SHORT_CN = "yyyy年MM月dd";

    /**
     * 中文全称 如：2010年12月01日 23时15分06秒
     */
    public static final String FORMAT_LONG_CN = "yyyy年MM月dd日  HH时mm分ss秒";

    /**
     * 精确到毫秒的完整中文时间
     */
    public static final String FORMAT_FULL_CN = "yyyy年MM月dd日  HH时mm分ss秒SSS毫秒";


    
    /**
     * 获取CalendarFactory对象
     *
     * @author zhaopengwei
     * @date 2017/12/14 8:50
     **/
    static final class CalendarFactory {
        public static CalendarFactory getFactory() {
            return instance;
        }
        
        private final ThreadLocal<Calendar> calendarRef = new ThreadLocal<Calendar>() {
            @Override
            protected Calendar initialValue() {
                return new GregorianCalendar();
            }
        };
        
        private static CalendarFactory instance = new CalendarFactory();
        
        /**
         * 私有构造方法
         */
        private CalendarFactory() {
        }
        
        public Calendar getCalendar() {
            return calendarRef.get();
        }
    }


    

    /**
     * 格式化日期
     *
     * @param date 日期
     * @param pattern 日期格式
     * @return
     */
    public static String format(final Date date, final String pattern) {
        if (date == null) {
            return null;
        }
        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(date);
    }


    /**
     * 获取两个日期的时间时间差 天(date2 - date1)
     *
     * @param date1 日期1
     * @param date2 日期2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        date1 = parseDate(format(date1, FORMAT_Y_M_D), FORMAT_Y_M_D);
        date2 = parseDate(format(date2, FORMAT_Y_M_D), FORMAT_Y_M_D);
        if (date1 != null && date2 != null) {
            return (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
        } else {
            return 0;
        }
    }

   /* *//**
     * 获取两个时间的差值（秒）date2 -date1
     *
     * @param date1 日期1
     * @param date2 日期2
     * @return
     *//*
    public static long differentSeconds(final Date date1, final Date date2) {
        //date1
        final Instant instant1 = date1.toInstant();
        final LocalDateTime localDate1 = instant1.atZone(ZONE_ID).toLocalDateTime();

        //date2
        final Instant instant2 = date2.toInstant();
        final LocalDateTime localDate2 = instant2.atZone(ZONE_ID).toLocalDateTime();
        return Duration.between(localDate1, localDate2).getSeconds();
    }*/

    /**
     * 获取给定时间的差值计算时间,秒置为0
     *
     * @param originTime 原始时间
     * @param field 字段
     * @param diff 时间差
     * @return
     */
    public static Date getTimeByFieldWithoutSeconds(final Date originTime, final int field, final int diff) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(originTime);
        if (field != 0 && diff != 0) {
            calendar.add(field, diff);
        }
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        final Date date = calendar.getTime();
        return date;
    }

    /**
     * 根据开始日期和间隔日期计算结束日期
     *
     * @param startDate
     * @param intervalDay
     * @return
     */
    public static Date getEndDate(final Date startDate, final int intervalDay) {

        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        if (intervalDay != 0) {
            calendar.add(Calendar.DAY_OF_YEAR, intervalDay);
            final Date endDate = calendar.getTime();
            return endDate;
        }
        return startDate;
    }

    /**
     * 获取yyyyMMdd日期
     *
     * @param time 时间
     * @return
     */
    public static Date convertTimeToDate(final Date time) {
        return parseDate(format(time, FORMAT_Y_M_D), FORMAT_Y_M_D);
    }


    /**
     * 获取指定时间之前或之后的时间，精确到小时
     *
     * @param date 日期
     * @param dayNum 前几天或者后几天
     * @param hourNum 具体到小时
     * @return
     */
    public static Date getDateBeforeOrAfter(final Date date, final Integer dayNum, final Integer hourNum) {
        final Calendar calendarHandler = Calendar.getInstance();
        calendarHandler.setTime(date);
        calendarHandler.add(Calendar.DAY_OF_MONTH, dayNum);
        final Date beforeDate = convertTimeToDate(calendarHandler.getTime());

        final Calendar calendarHandler2 = Calendar.getInstance();
        calendarHandler2.setTime(beforeDate);
        calendarHandler2.add(Calendar.HOUR_OF_DAY, hourNum);

        final Date resultDate = calendarHandler2.getTime();
        return resultDate;
    }

    /**
     * 转换时间戳(本方法仅适用于特定格式的解析)
     *
     * @param str 时间戳(必须符合/Date(time+GMT)/格式)
     * @return 返回String
     */
    public static String convertTimeStamp(String str) {
        if (Check.isEmpty(str)) {
            return "";
        }
        str = str.replace("/Date(", "").replace(")/", "");
        final String time = str.substring(0, str.length() - 5);
        final Date date = new Date(Long.parseLong(time));
        final SimpleDateFormat format = new SimpleDateFormat(DateUtil.FORMAT_Y_M_D_H_M_S);
        final String afterConvert = format.format(date);
        return afterConvert;
    }

    /**
     * 转换时间戳(本方法仅适用于特定格式的解析)
     *
     * @param str 时间戳(必须符合/Date(time+GMT)/格式)
     * @return 返回Date
     */
    public static Date convertTimeStampToDate(String str) {
        if (Check.isEmpty(str)) {
            return null;
        }
        str = str.replace("/Date(", "").replace(")/", "");
        final String time = str.substring(0, str.length() - 5);
        final Date date = new Date(Long.parseLong(time));
        return date;
    }


    /**
     * 创建开始时间特定的时间戳
     *
     * @return /Date(time+GMT)/格式的时间
     */
    public static String createEndTimeStamp() {
        final StringBuilder sb = new StringBuilder();
        final long timeInMillis = Calendar.getInstance().getTimeInMillis();
        final StringBuilder timeStamp = sb.append("/Date(").append(timeInMillis).append("+0800").append(")/");
        return timeStamp.toString();
    }

    /**
     * 创建结束时间特定的时间戳
     *
     * @return /Date(time+GMT)/格式的时间
     */
    public static String createStartTimeStamp(final int enviorment) {
        final StringBuilder sb = new StringBuilder();
        long timeInMillis = 0L;
        if (enviorment == 1) {
            timeInMillis = createCalendar().getTimeInMillis();
        } else {
            timeInMillis = createBeforeMinute().getTimeInMillis();
        }
        final StringBuilder timeStamp = sb.append("/Date(").append(timeInMillis).append("+0800").append(")/");
        return timeStamp.toString();
    }

    /**
     * 创建过去两天的calendar
     *
     * @return
     */
    public static Calendar createCalendar() {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, -1);
        return calendar;
    }

    /**
     * 创建前一分钟的calendar
     */
    public static Calendar createBeforeMinute() {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, -1);
        return calendar;
    }
    
    /**
     * 比较2个日期的大小
     *
     * @param dt1
     * @param dt2
     * @return
     */
    public static int compareDate(final Date dt1, final Date dt2) {
        if (dt1 == null || dt2 == null) {
            return 0;
        }
        try {
            if (dt1.getTime() > dt2.getTime()) {
                return 1;
            } else if (dt1.getTime() < dt2.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (final Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }
    
    /**
     * 比较2个日期的大小
     *
     * @param sdt1
     * @param sdt2
     * @param format
     * @return
     */
    public static int compareDate(final String sdt1, final String sdt2, final String format) {
        final Date dt1 = DateUtil.parseDate(sdt1, format);
        final Date dt2 = DateUtil.parseDate(sdt2, format);
        
        return compareDate(dt1, dt2);
    }
    
    /**
     * 日期时间转字符串
     *
     * @param date Date
     * @return 日期时间字符串(DEFAULT_DATETIME_FORMAT - - yyyy - MM - dd HH : mm : ss)
     */
    public static String dateTimeToString(final Date date) {
        return dateTimeToString(date, DEFAULT_DATETIME_FORMAT);
    }
    
    /**
     * 日期时间转字符串
     *
     * @param date   Date
     * @param format 日期时间字符串格式
     * @return 日期时间字符串
     */
    public static String dateTimeToString(final Date date, final String format) {
        if (date != null) {
            final SimpleDateFormat formatter = new SimpleDateFormat(format);
            return formatter.format(date);
        }
        return null;
    }
    
    /**
     * 日期转字符串
     *
     * @param date Date
     * @return 日期字符串(DEFAULT_DATE_FORMAT)
     */
    public static String dateToString(final Date date) {
        return dateTimeToString(date, DEFAULT_DATE_FORMAT);
    }
    
    /**
     * 日期转字符串
     *
     * @param date Date
     * @return 日期字符串(DEFAULT_DATE_FORMAT)
     */
    public static String dateToListString(final Date date) {
        return dateTimeToString(date, LIST_DATE_FORMAT);
    }
    
    /**
     * 对日期按照指定的类型进行添加或者减少
     *
     * @param date
     * @param type
     * @param num
     * @return
     */
    public static Date getAddDate(final Date date, final int type, final int num) {
        final Calendar cal = CalendarFactory.getFactory().getCalendar();
        try {
            cal.setTime(date);
            switch (type) {
                case ADD_TYPE_DATE:
                    cal.add(Calendar.DATE, num);
                    break;
                case ADD_TYPE_HOUR:
                    cal.add(Calendar.HOUR, num);
                    break;
                case ADD_TYPE_MINUTE:
                    cal.add(Calendar.MINUTE, num);
                    break;
                case ADD_TYPE_SECOND:
                    cal.add(Calendar.SECOND, num);
                    break;
                case ADD_TYPE_MONTH:
                    cal.add(Calendar.MONTH, num);
                    break;
                case ADD_TYPE_YEAR:
                    cal.add(Calendar.YEAR, num);
                    break;
                default:
                    break;
            }
        } catch (final Throwable e) {
            e.printStackTrace();
        }
        return cal.getTime();
    }
    
    public static void main(String[] args) {
        System.out.println(getDate(getFirstDayOfMonth(new Date()),0,0,0));
        System.out.println(getFirstDayOfLastMonth(new Date()));
        //System.err.println(getAddDate(new Date(),1,20));
    }
    
    /**
     * 获取当前的日期，格式是yyyy-mm-dd
     *
     * @return
     */
    public static Date getCurrentDate() {
        return DateUtil.parseDate(DateUtil.dateToString(new Date()));
    }
    
    /**
     * 获取指定时分秒的日期
     *
     * @param date
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    public static Date getDate(final Date date, final int hour, final int minute, final int second) {
        final Calendar calendar = CalendarFactory.getFactory().getCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }
    
    /**
     * 获取日期的开始时间 "2018-07-07 00:00:00"
     *
     * @param date
     * @return java.util.Date
     * @author wangdongxing
     * @since 2018/8/2 11:53
     */
    public static Date getDateTimeStart(Date date) {
        Date dateTimeStart = null;
        if (date != null) {
            String dateTimeStartString = dateToString(date) + " 00:00:00";
            dateTimeStart = parseDateTime(dateTimeStartString);
        }
        return dateTimeStart;
    }
    
    /**
     * 获取日期的最后时间 "2018-07-07 23:59:59"
     *
     * @param date
     * @return java.util.Date
     * @author wangdongxing
     * @since 2018/8/2 11:53
     */
    public static Date getDateTimeEnd(Date date) {
        Date dateTimeEnd = null;
        if (date != null) {
            String dateTimeEndString = dateToString(date) + " 23:59:59";
            dateTimeEnd = parseDateTime(dateTimeEndString);
        }
        return dateTimeEnd;
    }
    
    /**
     * 获取当前时间所在月的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfMonth(final Date date) {
        final Calendar lastDate = CalendarFactory.getFactory().getCalendar();
        lastDate.setTime(date);
        lastDate.set(Calendar.DAY_OF_MONTH, 1);
        return lastDate.getTime();
    }
    
    /**
     * 获取当前时间上个月的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfLastMonth(final Date date){
        //获取前一个月第一天
        final Calendar lastDate = CalendarFactory.getFactory().getCalendar();
        lastDate.setTime(date);
        lastDate.add(Calendar.MONTH, -1);
        lastDate.set(Calendar.DAY_OF_MONTH, 1);
        return lastDate.getTime();
    }
    
    /**
     * 取得某天所在星期的第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfWeek(final Date date) {
        final Calendar cal = CalendarFactory.getFactory().getCalendar();
        cal.setTime(getLastDayOfWeek(date));
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.add(Calendar.DAY_OF_WEEK, cal.get(Calendar.DAY_OF_WEEK) - 1 - Calendar.DAY_OF_WEEK);
        return cal.getTime();
    }
    
    /**
     * 根据不同的类型得到不同的格式化工具类
     *
     * @param num
     * @return
     */
    private static SimpleDateFormat getFormat(final int num) {
        SimpleDateFormat df = null;
        switch (num) {
            case DateUtil.H_M:
                df = new SimpleDateFormat("HH:mm");
                break;
            case DateUtil.H_M_S:
                df = new SimpleDateFormat("HH:mm:ss");
                break;
            case DateUtil.Y_H_M:
                df = new SimpleDateFormat("yyyy-MM-dd");
                break;
            case DateUtil.Y_H_M_H_M:
                df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                break;
            case DateUtil.Y_H_M_H_M_S:
                df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                break;
            case DateUtil.Y:
                df = new SimpleDateFormat("yyyy年");
                break;
            case DateUtil.Y_H:
                df = new SimpleDateFormat("yyyy年MM月");
                break;
            case DateUtil.Y_H_M_H_M_S_2:
                df = new SimpleDateFormat("yyyyMMddHHmmss");
                break;
            case DateUtil.YMD_HM:
                df = new SimpleDateFormat("yyyy.MM.dd HH:mm");
                break;
            case DateUtil.MD:
                df = new SimpleDateFormat("MM.dd");
                break;
            case DateUtil.YMD:
                df = new SimpleDateFormat("yy.MM.dd");
                break;
            case DateUtil.YMD_2:
                df = new SimpleDateFormat("yyyyMMdd");
                break;
            
            case DateUtil.MD_CN:
                df = new SimpleDateFormat("MM月dd日");
                break;
            default:
                break;
        }
        return df;
    }
    
    /**
     * @param num  格式化类型标识
     * @param date 日期
     * @return Date对象
     * @description 返回格日期
     */
    public static Date getFormatDate(final int num, final Date date) {
        Date resultDate = null;
        if (date == null) {
            return null;
        }
        final SimpleDateFormat df = getFormat(num);
        try {
            if (df != null) {
                final String stringDate = df.format(date);
                resultDate = df.parse(stringDate);
            }
        } catch (final ParseException e) {
            e.printStackTrace();
        }
        return resultDate;
    }
    
    /**
     * @param num        格式化类型标识
     * @param stringDate 日期的字符串形式
     * @return Date对象
     * @description 返回格日期
     */
    public static Date getFormatDate(final int num, final String stringDate) {
        Date resultDate = null;
        final SimpleDateFormat df = getFormat(num);
        try {
            if (df != null) {
                resultDate = df.parse(stringDate);
            }
        } catch (final ParseException e) {
            e.printStackTrace();
        }
        return resultDate;
    }
    
    /**
     * @param num  类型
     * @param date 需要处理的日期
     * @return 返回需要的日期字符串形式
     * @description 返回格式化字符串型日期
     */
    public static String getFormatString(final int num, final Date date) {
        if (date == null) {
            return "";
        } else {
            final SimpleDateFormat df = getFormat(num);
            return df == null ? "" : df.format(date);
        }
    }
    
    /**
     * 得到“时”
     *
     * @param date
     * @return
     */
    public static int getHourOfDate(final Date date) {
        final Calendar calendar = CalendarFactory.getFactory().getCalendar();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }
    
    /**
     * 获取当前时间所在月的最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(final Date date) {
        final Calendar lastDate = CalendarFactory.getFactory().getCalendar();
        
        lastDate.setTime(date);
        lastDate.set(Calendar.DATE, 1);
        lastDate.roll(Calendar.DATE, -1);
        
        return lastDate.getTime();
    }
    
    /**
     * 获取本周最后一天
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfWeek(final Date date) {
        final Calendar cal = CalendarFactory.getFactory().getCalendar();
        cal.setTime(date);
        // 以星期一Monday为一周的开始
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.add(Calendar.DAY_OF_WEEK, Calendar.DAY_OF_WEEK - cal.get(Calendar.DAY_OF_WEEK) + 1);
        return cal.getTime();
    }
    
    /**
     * 取得指定时间的前一天日期
     *
     * @return
     */
    public static Date getLastTimeByAppointDate(final Date date) {
        final Calendar cal = CalendarFactory.getFactory().getCalendar();
        try {
            cal.setTime(date);
            cal.add(Calendar.DATE, -1);
        } catch (final Exception e) {
            e.printStackTrace();
        }
        return cal.getTime();
    }
    
    /**
     * 取得指定时间的第二天日期
     *
     * @return
     */
    public static Date getNextTimeByAppointDate(final Date date) {
        final Calendar cal = CalendarFactory.getFactory().getCalendar();
        try {
            cal.setTime(date);
            cal.add(Calendar.DATE, 1);
        } catch (final Exception e) {
            e.printStackTrace();
        }
        return cal.getTime();
    }
    
    /**
     * 获取周一所在日期、按照每周周一-周日
     *
     * @param date
     * @return
     */
    public static Date getMonday(final Date date) {
        final Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        final int week = calendar.get(Calendar.DAY_OF_WEEK);
        //周日
        if (week == Calendar.SUNDAY) {
            return DateUtil.getAddDate(date, 1, -6);
        } else {
            return DateUtil.getAddDate(date, 1, Calendar.MONDAY - week);
        }
    }
    
    /**
     * 获取当前时间在今天的秒数
     *
     * @return
     */
    public static long getSecondsInDay() {
        final Calendar calendar = CalendarFactory.getFactory().getCalendar();
        calendar.setTime(new Date());
        final long hs = calendar.get(Calendar.HOUR) * 3600L;
        final long ms = calendar.get(Calendar.MINUTE) * 60L;
        final long s = calendar.get(Calendar.SECOND);
        return hs + ms + s;
    }
    
    /**
     * 获取指定日期的指定时间部分
     *
     * @param date
     * @param hour
     * @param minute
     * @param second
     * @return
     */
    public static Date getSpecialDate(final Date date, final int hour, final int minute, final int second) {
        final Calendar calendar = CalendarFactory.getFactory().getCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }
    
    /**
     * 获得两个日期的天、小时、分、秒差
     *
     * @param begin 开始时间
     * @param end   结束时间
     * @return 返回格式：0天1小时3分钟45秒
     */
    public static String getTwoDatesDif(final Date begin, final Date end) {
        final long total = begin.getTime() - end.getTime();
        final long seconds = total / 1000;
        final long day = seconds / 60 / 60 / 24;
        final long hour = (seconds - (day * 24 * 60 * 60)) / 60 / 60;
        final long minute = (seconds - (day * 24 * 60 * 60) - (hour * 60 * 60)) / 60;
        final long second = seconds - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60);
        return day + "天" + hour + "小时" + minute + "分钟" + second + "秒";
    }
    
    /**
     * 获得两个日期的天数差
     */
    public static int getTwoDatesDifDay(final Date begin, final Date end) {
        return getTwoDatesDifDay(getFormatString(DateUtil.Y_H_M, begin), getFormatString(DateUtil.Y_H_M, end));
    }
    
    /**
     * 获得两个日期的天数差
     */
    public static int getTwoDatesDifDay(final String beginStr, final String endStr) {
        final Date beginDay = getFormatDate(DateUtil.Y_H_M, beginStr);
        final Date endDay = DateUtil.getFormatDate(DateUtil.Y_H_M, endStr);
        long total = endDay.getTime() - beginDay.getTime();
        if (beginDay.after(endDay)) {
            total = beginDay.getTime() - endDay.getTime();
        }
        final long seconds = total / 1000;
        final long day = seconds / 60 / 60 / 24;
        return (int) day;
    }
    
    /**
     * 获取两日期的小时、分钟差
     *
     * @param begin
     * @param end
     * @return
     */
    public static String getTwoDatesDifHourMinute(final Date begin, final Date end) {
        final StringBuilder str = new StringBuilder("");
        final long total = end.getTime() - begin.getTime();
        final long seconds = total / 1000;
        final long day = seconds / 60 / 60 / 24;
        final long hour = (seconds - (day * 24 * 60 * 60)) / 60 / 60;
        final long minute = (seconds - (day * 24 * 60 * 60) - (hour * 60 * 60)) / 60;
        if (hour != 0) {
            str.append(hour).append("小时");
        }
        if (minute != 0) {
            str.append(minute).append("分");
        }
        
        return str.toString();
    }
    
    /**
     * 获得两个日期的天、小时、分、秒差
     *
     * @param begin 开始时间
     * @param end   结束时间
     * @return 返回格式：0天1小时3分钟45秒
     */
    public static String getTwoDatesDifNew(final Date begin, final Date end) {
        final StringBuilder str = new StringBuilder("");
        final long total = end.getTime() - begin.getTime();
        final long seconds = total / 1000;
        final long day = seconds / 60 / 60 / 24;
        final long hour = (seconds - (day * 24 * 60 * 60)) / 60 / 60;
        final long minute = (seconds - (day * 24 * 60 * 60) - (hour * 60 * 60)) / 60;
        final long second = seconds - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60);
        if (day != 0) {
            str.append(day).append("天");
        }
        if (hour != 0) {
            str.append(hour).append("小时");
        }
        if (minute != 0) {
            str.append(minute).append("分钟");
        }
        if (second != 0) {
            str.append(second).append("秒");
        }
        return str.toString();
    }
    
    /**
     * 获得两个日期的天、小时、分差
     *
     * @param begin 开始时间
     * @param end   结束时间
     * @return 返回格式：0天1小时3分钟
     */
    public static String getTwoDatesDifMin(final Date begin, final Date end) {
        final StringBuilder str = new StringBuilder("");
        final long total = end.getTime() - begin.getTime();
        final long seconds = total / 1000;
        final long day = seconds / 60 / 60 / 24;
        final long hour = (seconds - (day * 24 * 60 * 60)) / 60 / 60;
        final long minute = (seconds - (day * 24 * 60 * 60) - (hour * 60 * 60)) / 60;
        if (day != 0) {
            str.append(day).append("天");
        }
        if (hour != 0) {
            str.append(hour).append("小时");
        }
        if (minute != 0) {
            str.append(minute).append("分钟");
        }
        return str.toString();
    }
    
    /**
     * 获得两个日期的小时差
     *
     * @param begin 开始时间
     * @param end   结束时间
     * @return 相差小时数
     */
    public static float getTwoDatesDifOfHours(final Date begin, final Date end) {
        final long total = begin.getTime() - end.getTime();
        final long seconds = total / 1000;
        return seconds / 3600f;
    }
    
    /**
     * 获得两个日期的分
     *
     * @param begin 开始时间
     * @param end   结束时间
     * @return 返回格式：2
     */
    public static long getTwoDatesDifOfMin(final Date begin, final Date end) {
        final long total = begin.getTime() - end.getTime();
        final long seconds = total / 1000;
        final long day = seconds / 60 / 60 / 24;
        final long hour = (seconds - (day * 24 * 60 * 60)) / 60 / 60;
        final long minute = (seconds - (day * 24 * 60 * 60) - (hour * 60 * 60)) / 60;
        return minute;
    }
    
    /**
     * 获取两个日期的分钟差
     *
     * @param begin
     * @param end
     * @return
     */
    public static long getTwoDatesDifOfMinute(final Date begin, final Date end) {
        final long total = end.getTime() - begin.getTime();
        final long seconds = total / 1000;
        final long minute = seconds / 60;
        return minute;
    }
    
    /**
     * 取得某天是星期几
     */
    public static int getWeekOfDate(final Date dt) {
        final Calendar cal = CalendarFactory.getFactory().getCalendar();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return w;
    }
    
    /**
     * 获取当前的日期，格式是yyyy-mm-dd
     *
     * @return
     */
    public static Date getYMDDate() {
        final Calendar calendar = CalendarFactory.getFactory().getCalendar();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }
    
    /**
     * 获取指定时间的YYYY-MM-DD
     *
     * @param date
     * @return
     */
    public static Date getYMDDate(final Date date) {
        final Calendar calendar = CalendarFactory.getFactory().getCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }
    
    /**
     * 判断时间是否在时间段内
     *
     * @param date
     * @param dateBegin
     * @param dateEnd
     * @return
     */
    public static boolean isInDate(final Date date, final Date dateBegin, final Date dateEnd) {
        return date.getTime() >= dateBegin.getTime() && date.getTime() <= dateEnd.getTime();
    }
    
    /**
     * 判断时间是否在时间段内
     *
     * @param date
     * @param strDateBegin
     * @param strDateEnd
     * @return
     */
    public static boolean isInDate(final Date date, final String strDateBegin, final String strDateEnd) {
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        boolean flag = false;
        try {
            final Date dateBegin = sdf.parse(strDateBegin);
            final Date dateEnd = sdf.parse(strDateEnd);
            if (date.getTime() >= dateBegin.getTime() && date.getTime() <= dateEnd.getTime()) {
                flag = true;
            } else {
                flag = false;
            }
        } catch (final ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return flag;
    }
    
    /**
     * 解析日期
     *
     * @param sDate 日期字符串;格式 yyyy-MM-dd 或yyyyMMdd
     * @return Date
     */
    public static Date parseDate(final String sDate) {
        Date date = parseDate(sDate, DEFAULT_DATE_FORMAT);
        if (null == date) {
            date = parseDate(sDate, "yyyyMMdd");
        }
        return date;
    }
    
    /**
     * 解析日期
     *
     * @param sDate  日期字符串
     * @param format 格式
     * @return Date
     */
    public static Date parseDate(final String sDate, final String format) {
        Date date = null;
        if (Check.notEmpty(sDate)) {
            try {
                date = (Date) (new SimpleDateFormat(format)).parseObject(sDate);
            } catch (final ParseException e) {
                return date;
                // 不需要抛出异常
            }
        }
        return date;
    }
    /**
     * 增加天数，可以为正负值
     *
     * @param date
     *            Date
     * @param days
     *            天数可以为正负值
     * @return Date
     */
    public static Date addDays(final Date date, final int days)
    {
        final Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, days);
        final Date end = c.getTime();
        return end;
    }
    /**
     * 字符串转日期时间
     *
     * @param sDateTime 日期时间字符串(DEFAULT_DATETIME_FORMAT)
     * @return Date
     */
    public static Date parseDateTime(final String sDateTime) {
        Date oDateTime = null;
        if ((null != sDateTime) && (0 < sDateTime.length())) {
            try {
                oDateTime = (Date) (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parseObject(sDateTime);
            } catch (final ParseException e) {
                try {
                    oDateTime = (Date) (new SimpleDateFormat("yyyyMMddHHmmss")).parseObject(sDateTime);
                } catch (final ParseException e2) {
                    try {
                        oDateTime = (Date) (new SimpleDateFormat("HH:mm:ss")).parseObject(sDateTime);
                    } catch (final ParseException e3) {
                        try {
                            oDateTime = (Date) (new SimpleDateFormat("mm:ss")).parseObject(sDateTime);
                        } catch (final ParseException e4) {
                            return parseDate(sDateTime);
                        }
                    }
                }
            }
        }
        return oDateTime;
    }
    
    /**
     * 解析时间
     *
     * @param sTime 时间字符串;格式 HH:mm:ss
     * @return Date
     */
    public static Date parseTime(final String sTime) {
        Date time = null;
        if ((null != sTime) && (0 < sTime.length())) {
            try {
                time = (Date) (new SimpleDateFormat("HH:mm:ss")).parseObject(sTime);
            } catch (final ParseException e) {
                try {
                    time = (Date) (new SimpleDateFormat("HH:mm")).parseObject(sTime);
                } catch (final ParseException e2) {
                    try {
                        time = (Date) (new SimpleDateFormat("HH")).parseObject(sTime);
                    } catch (final ParseException e3) {
                        return time;
                        // 不需要抛出异常
                    }
                }
            }
        }
        return time;
    }
    
    /**
     * 取一个月前的日期
     *
     * @param month
     * @return
     */
    public static String retOneMonth(final Date month) {
        final Calendar cal = CalendarFactory.getFactory().getCalendar();
        cal.setTime(month);
        cal.add(Calendar.MONTH, -1);
        final String retMonth = DateUtil.getFormatString(DateUtil.Y_H_M, cal.getTime());
        
        return retMonth;
    }
    
    /**
     * 时间转字符串
     *
     * @param date Date
     * @return 时间字符串(DEFAULT_TIME_FORMAT)
     */
    public static String timeToString(final Date date) {
        return dateTimeToString(date, DEFAULT_TIME_FORMAT);
    }
    
    /**
     * 时间转字符串
     *
     * @param date   Date
     * @param format String
     */
    public static String timeToString(final Date date, final String format) {
        return dateTimeToString(date, format);
    }
    
    /**
     * 毫秒数转日期字符串
     *
     * @param currentTime
     * @param formatType
     * @return
     * @throws ParseException
     */
    public static String longToString(final long currentTime, final String formatType) throws ParseException {
        // long类型转成Date类型
        final Date date = longToDate(currentTime, formatType);
        // date类型转成String
        final String strTime = dateToString(date, formatType);
        return strTime;
    }
    
    /**
     * 毫秒数转Date
     *
     * @param currentTime
     * @param formatType
     * @return
     * @throws ParseException
     */
    public static Date longToDate(final long currentTime, final String formatType) throws ParseException {
        // 根据long类型的毫秒数生命一个date类型的时间
        final Date dateOld = new Date(currentTime);
        // 把date类型的时间转换为string
        final String sDateTime = dateToString(dateOld, formatType);
        // 把String类型转换为Date类型
        final Date date = stringToDate(sDateTime, formatType);
        return date;
    }
    
    /**
     * date类型转换为String类型
     *
     * @param data
     * @param formatType
     * @return
     */
    public static String dateToString(final Date data, final String formatType) {
        return new SimpleDateFormat(formatType).format(data);
    }

    /**
     * 比较两个时间
     * @param date1
     * @param date2
     * @return
     */
    public static int compareToTime(final long date1, final long date2) {
        final long l = date1 - date2;
        int i = 10;
        if (l > 0L) {
            i = 1;
        } else if (l == 0L) {
            i = 0;
        } else if (l < 0L) {
            i = -1;
        }
        return i;
    }

    /**
     * 日期转long
     *
     * @param date
     * @param format
     * @return
     */
    public static long dateTimeToLong(final Date date, final String format) throws ParseException {
        if (date != null) {
            final String s = DateUtil.dateTimeToString(date, format);
            return DateUtil.stringToDate(s, format).getTime();
        }

        return 0;
    }

    public static Date stringToDate(final String strTime, final String formatType) {
        final SimpleDateFormat formatter = new SimpleDateFormat(formatType);
        Date date = null;
        try {
            date = formatter.parse(strTime);
        } catch (final ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    
    
    /**
     * 私有构造方法
     */
    private DateUtil() {
    
    }
}
